

fn print_u8(s: &[u8]) {
    let s = unsafe {
        std::str::from_utf8_unchecked(s)
    };
    println!("{}", s);
}

#[derive(Debug, Clone, Copy)]
pub enum Item {
    Num(f32),
    Op(u8),
}

impl Item {

    pub fn num(&self) -> f32 {
        match self {
            Item::Num(v) => *v,
            Item::Op(_) => panic!("invalid item num")
        }
    }

    pub fn op(&self) -> u8 {
        match self {
            Item::Num(_) => panic!("invalid op"),
            Item::Op(op) => *op,
        }
    }
}

fn exprs_len(s: &[u8]) -> usize {

    let mut index = 0;
    let mut count = 0;

    for v in s.iter() {
        match *v {
            b'(' => count += 1,
            b')' => count -= 1,
            _ => {}
        }
        index += 1;

        if count < 0 {
            panic!("无效的字符:{:#?}", s);
        } else if count == 0 {
            break;
        }
    }

    if count != 0 {
        panic!("错误的表达式:{:#?}", s);
    }

    index
}

fn num_len(s: &[u8]) -> usize {
    let mut index = 0;
    for item in s.iter() {
        let v = *item;
        if (v >= b'0') && (v <= b'9') {
            index += 1;
        } else {
            break;
        }
    }
    index
}

fn is_primary(op: u8) -> bool {
    (op == b'*') ||
    (op == b'/')
}

fn calc(left: f32, op: u8, right: f32) -> f32 {

    match op {
        b'+' => left + right,
        b'-' => left - right,
        b'*' => left * right,
        b'/' => left / right,
        _=> panic!("invalid op")
    }
}

fn exprs_value(item_vec: &mut Vec<Item>) -> f32 {

    if item_vec.len() < 3 {
        return item_vec[0].num();
    }

    let mut op_index: usize = 1;

    while op_index < item_vec.len() {
        let op = item_vec[op_index].op();
        if is_primary(op) {
            break;
        }
        op_index += 2;
    }

    if op_index >= item_vec.len() {
        op_index = 1;
    }

    let left = item_vec[op_index - 1].num();
    let op = item_vec[op_index].op();
    let right = item_vec[op_index + 1].num();
    let result = calc(left, op, right);

    item_vec[op_index-1] = Item::Num(result);
    item_vec.remove(op_index);
    item_vec.remove(op_index);

    exprs_value(item_vec)
}

fn parse_exprs(s: &[u8]) -> f32 {

//  print_u8(s);
    
    let size = s.len();
    let mut index = 0;

    let mut item_vec = Vec::new();

    while index < size {

        let v = s[index];

        match v {

            b'(' => {
                let expr_len = exprs_len(&s[index..]);
                assert!(expr_len >= 2, "expr len 必须 大于2");
                let num = parse_exprs(&s[(index+1)..(index+expr_len-1)]);
                index += expr_len;

                item_vec.push( Item::Num(num) );

                continue;
            }

            b' ' => {
            }

            b'0'..=b'9' => {
                let num_len = num_len(&s[index..]);
                assert!(num_len > 0, "num len > 0");
                let num = &s[index..(index+num_len)];
                let num: f32 = unsafe {
                    std::str::from_utf8_unchecked(num)
                }.parse().unwrap();
              //  println!("num:{}", num);

                item_vec.push( Item::Num(num) );

                index += num_len;
                continue;
            }

            b'+' => {
                item_vec.push( Item::Op(b'+') );
            }

            b'-' => {
                item_vec.push( Item::Op(b'-') );
            }

            b'*' => {
                item_vec.push( Item::Op(b'*') );
            }

            b'/' => {
                item_vec.push( Item::Op(b'/') );
            }

            _ => {
                panic!("无法处理的字符");
            }
        };

        index += 1;
    }

    exprs_value(&mut item_vec)
}

pub fn expr3_test() {
    let exprs = "1+2*(9-3)*3/(12-4)+3*(9-23*(3-4))";
    println!("表达式:{}", exprs);
    let v = parse_exprs(exprs.as_bytes());
    println!("结果={}", v);
}







